﻿using System;
using System.Collections.Generic;
using System.Text;
using DomenModel;
using System.Web.Security;
using System.Configuration;
using Infrastructure.Repositories;
using Model.Repositories;
using Model.Service;
using Model.Repositories.Interfaces;
using System.Web.Mvc;

namespace Infrastructure.Service
{
    public class AuthorizationProvider : MembershipProvider, IAuthorizationProvider
    {
        private IUserCrud _dbUsers;
        public const int MAX_ONLINE_USERS = 50;
        Dictionary<string, DateTime> usersLastActivityDateDictionary = new Dictionary<string, DateTime>();

        public AuthorizationProvider(IUserCrud _dbUsers)
        {
            this._dbUsers = _dbUsers;
        }

        public AuthorizationProvider()
        {
            this._dbUsers = DependencyResolver.Current.GetService<IUserCrud>();
        }


        public override string ApplicationName
        {
            get
            {
                return ApplicationName;
            }
            set
            {
                ApplicationName = value;
            }
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            return false;
        }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotImplementedException();
        }

        public  bool CreateUser(string loginName, string firstName, string lastName, string password, string email, string region, int roleId, int balance, int statusId /*, bool isApproved, object providerUserKey, out MembershipCreateStatus status */)
        {
            var check = _dbUsers.GetByLogin(loginName);
            if (check == null)
            {
                User user = new User
                {
                    LoginName = loginName,
                    FirstName = firstName,
                    LastName = lastName,
                    Password = password,
                    Email = email,
                    Region = region,
                    RoleId = roleId,
                    Balance = balance,
                    StatusId = statusId
                };
                _dbUsers.Save(user);
                return true;
            }
            return false;
        }
     
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotImplementedException();
        }

        public override bool EnablePasswordReset
        {
            get { return EnablePasswordReset; }
        }

        public override bool EnablePasswordRetrieval
        {
            get { return EnablePasswordRetrieval; }
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public User FindUserByName(string loginName)
        {
            return null;
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        #region GetUser_Method
        public User GetUser(string username)
        {
            //_dbUsers = new UserRealization();
            var user = _dbUsers.GetByLogin(username);
            return user;
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        #endregion

        public override string GetUserNameByEmail(string email)
        {
            var user = _dbUsers.GetByEmail(email);
            if (user == null) return null;
            return user.LoginName;
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { return MaxInvalidPasswordAttempts; }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { return MinRequiredNonAlphanumericCharacters; }
        }

        public override int MinRequiredPasswordLength
        {
            get { return MinRequiredPasswordLength; }
        }

        public override int PasswordAttemptWindow
        {
            get { return PasswordAttemptWindow; }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get { return PasswordFormat; }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { return PasswordStrengthRegularExpression; }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { return RequiresQuestionAndAnswer; }
        }

        public override bool RequiresUniqueEmail
        {
            get { return RequiresUniqueEmail; }
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }

        public override bool ValidateUser(string username, string password)
        {
            bool isValid = false;
            var user = _dbUsers.GetByLogin(username);
            if (user != null && _dbUsers.CheckHashPassword(username, password))
            {
                isValid = true;
                UpdateUserLastActivityDate(username);
            }
            return isValid;
        }

        public override int GetNumberOfUsersOnline()
        {
            int numberOfUsersOnline = 0;
            foreach (var user in usersLastActivityDateDictionary)
            {
                if (user.Value.AddMinutes(Membership.UserIsOnlineTimeWindow) >= DateTime.Now
                    && user.Key != null && user.Key != "")
                    numberOfUsersOnline++;
            }
            return numberOfUsersOnline;
        }

        public void UpdateUserLastActivityDate(string username)
        {
            if (username != null)
            {
                if (usersLastActivityDateDictionary.ContainsKey(username))
                    usersLastActivityDateDictionary[username] = DateTime.Now;
                else
                    usersLastActivityDateDictionary.Add(username, DateTime.Now);
            }
        }

        public bool IsMaxUsersOnline()
        {
            if (GetNumberOfUsersOnline() >= MAX_ONLINE_USERS)
                return true;
            else
                return false;
        }

        public Dictionary<string, DateTime> GetDictionaryOfUsersOnline()
        {
            Dictionary<string, DateTime> dictionaryOfUsersOnline = new Dictionary<string, DateTime>();
            foreach (var user in usersLastActivityDateDictionary)
            {
                if (user.Value.AddMinutes(Membership.UserIsOnlineTimeWindow) >= DateTime.Now)
                    dictionaryOfUsersOnline.Add(user.Key, user.Value);
            }
            return dictionaryOfUsersOnline;
        }

        public bool IsUserOnline(string username)
        {
            bool res = false;
            if (usersLastActivityDateDictionary.ContainsKey(username) &&
                usersLastActivityDateDictionary[username].AddMinutes(Membership.UserIsOnlineTimeWindow) >= DateTime.Now)
            {
                res = true;
            }
            return res;
        }

        public void LogOfUser(string username)
        {
            if (usersLastActivityDateDictionary.ContainsKey(username))
                usersLastActivityDateDictionary.Remove(username);
        }

        public List<User> GetListOfUsersOnline(List<User> listOfUser)
        {
            List<User> listOfUsersOnline = new List<User>();
            listOfUsersOnline = listOfUser.GetRange(0, listOfUser.Count);
            foreach (var user in listOfUser)
            {
                if (!IsUserOnline(user.LoginName))
                    listOfUsersOnline.Remove(user);
            }
            return listOfUsersOnline;
        }
    }
}
